package com.example.p2pinvest.ui;

import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.example.p2pinvest.R;
import com.example.p2pinvest.util.UIUtils;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;

import cz.msebera.android.httpclient.Header;

/**
 * @author h2tc01
 * @version 1.0.0
 * 2022/8/9
 * 加载页,包含 加载中 , 加载失败  ,空数据  ,加载成功 四种状态 四种页面
 */
public abstract class LoadingPage extends FrameLayout {

    //定义四种不同的显示状态
    private static final int STATE_LOADING = 1;  //加载中状态码
    private static final int STATE_ERROR = 2; //加载失败状态码
    private static final int STATE_EMPTY = 3;  //加载完成后数据为空状态码
    private static final int STATE_SUCCESS = 4;  //加载成功状态码

    //默认当前情况下是正在加载
    private int state_current = STATE_LOADING;

    //提供4中不同的界面
    private View view_loading;
    private View view_error;
    private View view_empty;
    private View view_success;

    private LayoutParams params;

    private Context context;

    public LoadingPage(@NonNull Context context) {
        this(context, null);
    }

    public LoadingPage(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LoadingPage(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init();
    }

    //初始化方法
    private void init() {
        params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        //实例化view
        //加载中
        if (view_loading == null) {
            //加载布局
            view_loading = UIUtils.getView(R.layout.page_loading);
            //添加到当前的frameLayout中
            addView(view_loading, params);
        }

        //空数据
        if (view_empty == null) {
            //加载布局
            view_empty = UIUtils.getView(R.layout.page_empty);
            //添加到当前的frameLayout中
            addView(view_empty, params);
        }

        //获取数据失败
        if (view_error == null) {
            //加载布局
            view_error = UIUtils.getView(R.layout.page_error);
            //添加到当前的frameLayout中
            addView(view_error, params);
        }

        //根据状态码决定显示哪层视图
        showSafePage();
    }

    //保证如下操作在主线程中执行
    private void showSafePage() {
        UIUtils.runOnUIThread(new Runnable() {
            @Override
            public void run() {
                showPage();
            }
        });
    }

    private void showPage() {
        //根据状态码决定显示哪一个view
        view_loading.setVisibility(state_current == STATE_LOADING ? View.VISIBLE : View.INVISIBLE);
        view_error.setVisibility(state_current == STATE_ERROR ? View.VISIBLE : View.INVISIBLE);
        view_empty.setVisibility(state_current == STATE_EMPTY ? View.VISIBLE : View.INVISIBLE);

        if (view_success == null) {
            //成功视图即原本要展示的fragment
            //view_success = UIUtils.getView(layoutId());   //加载布局使用的是application的context,导致样式失效
            view_success = View.inflate(context, layoutId(), null);  //使用MainActivity的context加载fragment
            addView(view_success, params);
        }
        view_success.setVisibility(state_current == STATE_SUCCESS ? View.VISIBLE : View.INVISIBLE);
    }

    public abstract int layoutId();

    private ResultState resultState;

    /**
     * 在show()方法中实现联网加载数据
     */
    public void show() {
        String url = url();
        if (TextUtils.isEmpty(url)) {
            //如果url为空,则说明有些页面不需要联网,直接返回
            resultState = ResultState.SUCCESS;
            resultState.setContent("");
            loadImage();
            return;
        }

        AsyncHttpClient client = new AsyncHttpClient();

        //延迟加载,模拟网络请求效果,生产环境需删除
        UIUtils.getHandler().postDelayed(() -> {
            client.get(url, params(), new AsyncHttpResponseHandler() {
                @Override
                public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                    String response = new String(responseBody, StandardCharsets.UTF_8);
                    if (TextUtils.isEmpty(response)) {
                        //state_current = STATE_EMPTY;
                        resultState = ResultState.EMPTY;   //空数据
                        resultState.setContent("");
                    } else {
                        //state_current = STATE_SUCCESS;
                        resultState = ResultState.SUCCESS;  //请求成功
                        resultState.setContent(response);
                    }
                    //showSafePage();
                    loadImage();
                }

                @Override
                public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                    //state_current = STATE_ERROR;  //请求失败,变更状态码
                    resultState = ResultState.ERROR;
                    resultState.setContent("");
                    //showSafePage();  //重新展示view
                    loadImage();
                }

            });
        }, 1000);
    }

    private void loadImage() {
        switch (resultState) {
            case EMPTY:
                state_current = STATE_EMPTY;
                break;
            case SUCCESS:
                state_current = STATE_SUCCESS;
                break;
            case ERROR:
                state_current = STATE_ERROR;
                break;
        }
        //根据修改以后的state_current的值更新视图
        showSafePage();
        //如果state_current为成功状态,则处理传输数据
        if (state_current == STATE_SUCCESS) {
            //传输json数据
            onSuccess(resultState, view_success);
        }
    }

    /**
     * 网络请求成功后的数据处理方法,是一个回调方法
     *
     * @param resultState  枚举,包含请求结果和返回数据
     * @param view_success 展示数据的视图
     */
    protected abstract void onSuccess(ResultState resultState, View view_success);

    /**
     * 联网的请求参数
     *
     * @return
     */
    protected abstract RequestParams params();

    /**
     * 联网的请求地址
     *
     * @return
     */
    public abstract String url();

    /**
     * 提供枚举类型,封装网络请求返回的状态值和数据
     */
    public enum ResultState {

        ERROR(2), EMPTY(3), SUCCESS(4);

        int state;

        ResultState(int state) {
            this.state = state;
        }

        private String content;   //请求成功后的返回数据

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }
}
